package com.itdct.onflow.system.file.manager.upload

import com.itdct.onflow.core.config.OnflowConfig
import com.itdct.onflow.core.constant.FileStoreTypeConst
import com.itdct.onflow.system.file.entity.SysFileEntity
import io.minio.GetObjectArgs
import io.minio.MinioClient
import io.minio.PutObjectArgs
import io.minio.RemoveObjectArgs
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.stereotype.Component
import java.io.File
import java.io.InputStream

/**
 * @author Zhouwx
 * @date 2025/9/24 10:44:05
 * @version 1.0
 * @description
 */
@Component
@ConditionalOnProperty(name = ["onflow.file.container-type"], havingValue = "minio")
class MinioFileTransfer(
    val minioClient: MinioClient,
    val onflowConfig: OnflowConfig
) : BaseFileTransfer {
    companion object {
        val IMAGE_TYPE = arrayListOf("jpg", "jpeg", "png", "gif", "bmp", "webp")
    }

    override fun upload(sysFileEntity: SysFileEntity, file: File, deleteAfterUpload: Boolean) {
        if (!file.exists()) {
            throw RuntimeException("文件不存在")
        }
        if (!file.canRead()) {
            throw RuntimeException("文件不可读")
        }
        if (!file.isFile) {
            throw RuntimeException("文件不是文件")
        }
        if (file.length() > 1024 * 1024 * 1024) {
            throw RuntimeException("文件大小不能超过1G")
        }
        var contentType = ""
        if (IMAGE_TYPE.contains(file.extension.lowercase())) {
            contentType = "image/${file.extension}"
        }
        // 将文件转为文件流并上传到minio中
        file.inputStream().use { inputStream ->
            val builder = PutObjectArgs.builder()
                .bucket(sysFileEntity.bucketName)
                .`object`(sysFileEntity.storePath)
                .stream(inputStream, file.length(), -1)

            if (contentType != "") {
                builder.contentType(contentType)
            }

            val putObjectArgs = builder.build()
            minioClient.putObject(putObjectArgs)
        }

        if (deleteAfterUpload) {
            file.delete()
        }
    }

    override fun download(storePath: String): InputStream {
        val bucketName = onflowConfig.file.bucketName
        return minioClient.getObject(
            GetObjectArgs.builder()
                .bucket(bucketName)
                .`object`(storePath)
                .build()
        )
    }

    override fun delete(sysFileEntity: SysFileEntity) {
        val bucketName = onflowConfig.file.bucketName
        minioClient.removeObject(
            RemoveObjectArgs.builder()
                .bucket(bucketName)
                .`object`(sysFileEntity.storePath)
                .build()
        )
    }

    override fun getType(): String {
        return FileStoreTypeConst.MINIO
    }
}